#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include<time.h>
#include<gmp.h>


#define NUMTHR 8  // Numero total de threads

int NumPtos [NUMTHR]; // Total de pontos da thread
int NumPtosCirc[NUMTHR]; // Pontos no circulo

void *SortCalc (void *param) {

	int i, thrnum = *((int *)param); // O número da thread ()
	double px,py,dist;
	NumPtos[thrnum] = 0;
	NumPtosCirc[thrnum] = 0;

	for (i = 0; i<1000000; i++){
		px = drand48(); // sorteia um número entre 0 e 1
		py = drand48(); // sorteia um número entre 0 e 1
		dist = ((px*px) + (py*py));
		// Se a distancia for <= 1 entao o ponto esta dentro do circulo
		if (dist <= 1){
			NumPtosCirc[thrnum] ++; // contador de pontos dentro do círculo
		}

		NumPtos[thrnum] ++; // incrementa os pontos totais da thread (0 a 9)
	}
	pthread_exit(0);
}

int main (int argc, char *argv[]){

	int i, j, TotalPtos = 0, TotalCirc = 0;
	pthread_t ThreadID[NUMTHR];  // ID das threads
	srand48(time(NULL));

	mpf_t Pi;  // armazenará o valor de pi
	mpf_t Circulo;
	mpf_t Quadrado;

	/*Inicializa as variaveis da gmp*/
    mpf_init(Pi);
    mpf_init(Circulo);
    mpf_init(Quadrado);

    /*atribui valor 0 as variaveis gmp*/
    mpf_set_ui(Pi,0);
    mpf_set_ui(Circulo,0);
    mpf_set_ui(Quadrado,0);

	printf("Calculando pi...\n");
	// Cria a i-esima thread
	for (i = 0; i< NUMTHR ; i++){
		pthread_create (&ThreadID[i], NULL, SortCalc, &i);
    }

	// Espera as threads terminem
	for (i = 0; i< NUMTHR ; i++){
		pthread_join (ThreadID[i], NULL);
    }

    for (i = 0; i< NUMTHR ; i++){
        TotalPtos += NumPtos[i];  // TotalPtos = TotalPtos + NumPtos[i]
        TotalCirc += NumPtosCirc[i]; // TotalCirc = TotalCirc + NumPtosCirc[i]
    }
    mpf_set_ui(Circulo,TotalCirc);//atribui o valor de TotalCirc a variavel gmp Circulo
    mpf_set_ui(Quadrado,TotalPtos);//atribui o valor de TotalPtos a variavel gmp Quadrado

    /*Temos que: PI = 4 * Área_círculo/Área_quadrado => 4 * Pontos_no_círculo/Total_de_pontos. */
	mpf_div(Pi,Circulo,Quadrado);
	mpf_mul_ui(Pi,Pi,4);
	gmp_printf("Valor de pi %.20Ff \n",Pi);
	return 0;
}
